﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Xml;
using System.IO;
using BlueSkySOA.Core.Logging;

namespace BlueSkySOA.Core.ProxyServer
{
    public class DefaultServerProxy: IServerProxy
    {
        const string PROXY_DATA_FILE = "ServerProxy.xml";
        private static IEnumerable<IWebProxy> WebProxyListInstance;
        private static int CurrentIndex;
        private IEnumerable<IWebProxy> WebProxyList {
            get {
                if (WebProxyListInstance == null) {
                    WebProxyListInstance = new List<IWebProxy>();
                    var directoryName = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
                    if (directoryName != null)
                    {
                        string assemblerPath = directoryName.Replace("file:\\", string.Empty);
                        string proxyDataFile = Path.Combine(assemblerPath, PROXY_DATA_FILE);
                        XmlDocument xmlDocument = new XmlDocument();
                        try
                        {
                            xmlDocument.Load(proxyDataFile);
                            if (xmlDocument.DocumentElement != null)
                            {
                                XmlNodeList nodeList = xmlDocument.DocumentElement.GetElementsByTagName("serverproxy");
                                foreach (XmlNode node in nodeList)
                                {
                                    if (node.Attributes != null)
                                    {
                                        string proxyAddress = string.Format("{0}:{1}", node.Attributes["ipaddress"].Value, node.Attributes["port"].Value);
                                        bool isByPass = true;
                                        bool.TryParse(node.Attributes["bypass"].Value, out isByPass);
                                        IWebProxy objWebProxy = new WebProxy(proxyAddress, isByPass);
                                        if (!string.IsNullOrEmpty(node.Attributes["username"].Value)
                                            && !string.IsNullOrEmpty(node.Attributes["password"].Value)
                                            && !string.IsNullOrEmpty(node.Attributes["domain"].Value))
                                        {
                                            ICredentials credential = new NetworkCredential(node.Attributes["username"].Value
                                                                                            , node.Attributes["password"].Value
                                                                                            , node.Attributes["domain"].Value
                                                );
                                            objWebProxy.Credentials = credential;
                                        }
                                        ((List<IWebProxy>) WebProxyListInstance).Add(objWebProxy);
                                    }
                                }
                            }
                        }
                        catch (Exception ex) 
                        {
                            LoggingFactory.GetLogger().Log(ex.ToString());
                        }
                    }
                }
                    
                return WebProxyListInstance;
                
            }
        }
        #region IServerProxy Members

        public IWebProxy GetNextWebProxy()
        {
            if (!WebProxyList.Any())
                return null;
            if (CurrentIndex == WebProxyList.Count())
            {
                CurrentIndex = 0;
                return null;
            }
            IWebProxy result = WebProxyList.ToList().ElementAt(CurrentIndex);
            CurrentIndex++;
            return result;
        }

        public void RemoveWebProxy(IWebProxy webProxy)
        {
            
             var directoryName = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase);
             if (directoryName != null)
             {
                 string assemblerPath = directoryName.Replace("file:\\", string.Empty);
                 string proxyDataFile = Path.Combine(assemblerPath, PROXY_DATA_FILE);
                 XmlDocument xmlDocument = new XmlDocument();
                 try
                 {
                     xmlDocument.Load(proxyDataFile);
                     if (xmlDocument.DocumentElement != null)
                     {
                         XmlNodeList nodeList = xmlDocument.DocumentElement.GetElementsByTagName("serverproxy");
                         foreach (XmlNode node in nodeList)
                         {
                             WebProxy objWebProxy = (WebProxy) webProxy;
                             if (node.Attributes["ipaddress"].Value.Equals(objWebProxy.Address.Host) && node.Attributes["port"].Value.Equals(objWebProxy.Address.Port))
                             {
                                 xmlDocument.DocumentElement.RemoveChild(node);
                                 LoggingFactory.GetLogger().Log(string.Format("Remove proxy: {0}:{1}", objWebProxy.Address.Host, objWebProxy.Address.Port));
                                 break;
                             }
                         }
                         xmlDocument.Save(proxyDataFile);
                     }
                     WebProxyList.ToList().Remove(webProxy);
                 }
                 catch (Exception ex)
                 {
                     LoggingFactory.GetLogger().Log(ex.ToString());
                 }
                 CurrentIndex--;
             }
             

        }

        #endregion
    }
}
